﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
    
namespace StringDefs.Web
{
    
    public static class Web
    {
        private static readonly Regex UrlsRegex = new Regex("(?<Protocol>\\w+):\\/\\/(?<Domain>[\\w@][\\w.:@]+)\\/?[\\w\\." + "?=%&=\\-@/$,]*",
            RegexOptions.IgnoreCase
            | RegexOptions.CultureInvariant
            | RegexOptions.IgnorePatternWhitespace
            | RegexOptions.Compiled
            );

        
        private static readonly Regex HyperlinkRegex = new Regex("href=\"(?<Link>.*?)\"",
            RegexOptions.IgnoreCase
            | RegexOptions.CultureInvariant
            | RegexOptions.IgnorePatternWhitespace
            | RegexOptions.Compiled
            );

        private static readonly Regex EmailRegex = new Regex("([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1" + ",3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})",
            RegexOptions.IgnoreCase
            | RegexOptions.CultureInvariant
            | RegexOptions.IgnorePatternWhitespace
            | RegexOptions.Compiled
            );

        public static readonly Regex IpRegex = new Regex("(?<First>2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.(?<Second>2[0-4]\\d" + "|25[0-5]|[01]?\\d\\d?)\\.(?<Third>2[0-4]\\d|25[0-5]|[01]?\\d" +
              "\\d?)\\.(?<Fourth>2[0-4]\\d|25[0-5]|[01]?\\d\\d?)",
            RegexOptions.IgnoreCase
            | RegexOptions.CultureInvariant
            | RegexOptions.IgnorePatternWhitespace
            | RegexOptions.Compiled
            );
            

        /// <summary>
        /// Deletes the tags from a HTML line
        /// </summary>
        /// <param name="codeLine"></param>
        /// <returns></returns>
        public static string StripTags(this string codeLine)
        {
            string tag = string.Empty;
            string html = string.Empty;
            var tags = new List<string>();
            for (int i = 0; i < codeLine.Length; i++)
            {
                tag = string.Empty;
                if (codeLine[i] == '<')
                {
                    i++;
                    do
                    {
                        tag = tag + codeLine[i];
                        i++;
                    } while (codeLine[i] != '>');
                    tags.Add("<" + tag + ">");
                }
            }

            foreach (string k in codeLine.Split(tags.ToArray(), StringSplitOptions.RemoveEmptyEntries))
                html = html + k + " ";

            return html;
        }

        /// <summary>
        /// Extracts all the hyperlinks (href=*.*) from given text.
        /// </summary>
        /// <param name="text">The text to be parsed.</param>
        /// <returns>List of unique hyperlinks found.</returns>
        public static List<string> ExtractHyperlinks(this string text)
        {
            var results = new List<string>();

            var matches = HyperlinkRegex.Matches(text);

            foreach (Match match in matches)
            {
                if (!results.Contains(match.Groups["Link"].Value))
                {
                    results.Add(match.Groups["Link"].Value);
                }
            }

            return results;
        }

        /// <summary>
        /// Extracts all the unique URLs (http://*.* or ftp://*.* etc) from the given text.
        /// </summary>
        /// <param name="text">The text to be parsed.</param>
        /// <returns>List of unique URLs found.</returns>
        public static List<string> ExtractUrls(this string text)
        {
            var results = new List<string>();

            var matches = UrlsRegex.Matches(text); 

            foreach (Match match in matches)
            {
                if (!results.Contains(match.Value))
                {
                    results.Add(match.Value);
                }
            }

            return results;
        }

        /// <summary>
        /// Extracts all the unique emails from the given text.
        /// </summary>
        /// <param name="text">The text to be parsed.</param>
        /// <returns>List of unique emails found.</returns>
        public static List<string> ExtractEmailAddresses(this string text)
        {
            var results = new List<string>();

            var matches = EmailRegex.Matches(text);

            foreach (Match match in matches)
            {
                if (!results.Contains(match.Value))
                {
                    results.Add(match.Value);
                }
            }

            return results;        
        }

        /// <summary>
        /// Extracts all the unique IP addresses.
        /// </summary>
        /// <param name="text">The text to be parsed.</param>
        /// <returns>List of unique IP addresses found.</returns>
        public static List<string> ExtractIpAddresses(this string text)
        {
            var results = new List<string>();

            var matches = IpRegex.Matches(text);

            foreach (Match match in matches)
            {
                if (!results.Contains(match.Value))
                {
                    results.Add(match.Value);
                }
            }

            return results;
        }

        /// <summary>
        /// Extracts the base domain from a site
        /// </summary>
        /// <param name="url">the complete website URL</param>
        /// <returns></returns>
        /// <remarks>This is broken right now and so I commented it out</remarks>
        //public static string ExtractBaseDomain(this string url)
        //{
        //    //http://www.world.com
        //    //if (text.Contains("://"))
        //    //    text = text.Substring(text.IndexOf("://") + "://".Length);
        //    url =  url.Substring(url.IndexOf('/'));
        //    if (url.IndexOf('/') != -1)
        //        return url.Substring(url.IndexOf('/'));
        //    else
        //        return url;
        //}

        /// <summary>
        /// Returns whether a 
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        //public static bool IsBaseDomain(this string url)
        //{
        //    return url.ExtractBaseDomain().ToLower().Equals(url.ToLower()); 
        //}

        //public static string Protocol(this string url)
        //{
        //    return url.Substring(0, url.IndexOf(':'));
        //}
        

    }
}
